import * as d3 from "d3";
import { Scale } from "./scale"

import { grad2rad } from "./functions";


export interface IArrow {
    scale: Scale
    value: number
}

export const defaultInitArrowSettings: IArrow = {
    value: 0,
    scale: new Scale()
}

export class Arrow {

    svg = d3.create("svg:g");
    arrow: any = null;
    value = 0;

    constructor(private settings: IArrow = defaultInitArrowSettings) {
        
        this.drawArrow();

    }

    drawArrow() {
        let point = this.calcRadiusPoints(grad2rad(this.settings.scale.calc(this.settings.value)), 300);

        let link: [number, number][] = [[300, 300],[point.x, point.y]];
        this.arrow = this.svg.append("path")
                .attr("d", d3.line()(link))
                .attr("stroke-width", 4)
                .style("stroke", "red");
            // .attr("x1", 300)     // x position of the first end of the line
            // .attr("y1", 300)      // y position of the first end of the line
            // .attr("x2", point.x)     // x position of the second end of the line
            // .attr("y2", point.y)    // y position of the second end of the line
            // .transition()
            // .duration(1000)
    }

    private calcRadiusPoints(angle: number, radius: number) {
        const x = 300 + Math.sin(angle) * radius;
        const y = 300 + Math.cos(angle) * radius;
        return {"x": x, "y": y};
    }

    getSVG() {
        return this.svg;
    }
    getInterpolator(v: number) {

        let interpolateArray: any[] = [];
        let corr = 5;
        if (v < this.value) {corr = -5;}

        while (Math.abs(Math.abs(this.value) - Math.abs(v)) > 5) {
            let point = this.calcRadiusPoints(grad2rad(this.settings.scale.calc(this.value)), 300);
            let link: [number, number][] = [[300, 300],[point.x, point.y]];
            interpolateArray.push(d3.line()(link));
            this.value += corr;
        }
        let point = this.calcRadiusPoints(grad2rad(this.settings.scale.calc(v)), 300);
        let link: [number, number][] = [[300, 300],[point.x, point.y]];
        interpolateArray.push(d3.line()(link));
        this.value = v;
        
        return () => d3.interpolateDiscrete(interpolateArray);
    }

    setValue(value: number) {
        //console.log(value);
        this.arrow.transition()
            .ease(d3.easeLinear)
            .duration(500)
            .attrTween("d", this.getInterpolator(value))
    }}